package com.umessage.hotel.rest;

import java.io.InputStream;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.concurrent.TimeUnit;

import javax.servlet.ServletRequest;

import org.apache.commons.lang.StringUtils;
import org.redisson.api.RBlockingQueue;
import org.redisson.api.RDelayedQueue;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.riversoft.weixin.pay.util.SignatureUtil;
import com.umessage.common.annotation.Log;
import com.umessage.common.service.RedissonService;
import com.umessage.hotel.dao.OrderInfoMapper;
import com.umessage.hotel.domain.Coupon;
import com.umessage.hotel.domain.MemberAccountLog;
import com.umessage.hotel.domain.MemberCoupon;
import com.umessage.hotel.domain.MemberInfo;
import com.umessage.hotel.domain.OrderBreakfast;
import com.umessage.hotel.domain.OrderInfo;
import com.umessage.hotel.domain.RoomInfo;
import com.umessage.hotel.domain.WxCfg;
import com.umessage.hotel.model.FormModel;
import com.umessage.hotel.model.OrderModel;
import com.umessage.hotel.model.OrderParam;
import com.umessage.hotel.model.PayResult;
import com.umessage.hotel.model.PaySignModel;
import com.umessage.hotel.model.RoomModel;
import com.umessage.hotel.service.BreakfastCouponService;
import com.umessage.hotel.service.CouponService;
import com.umessage.hotel.service.FormService;
import com.umessage.hotel.service.MemberAccountLogService;
import com.umessage.hotel.service.MemberCouponService;
import com.umessage.hotel.service.MemberInfoService;
import com.umessage.hotel.service.OrderBreakfastService;
import com.umessage.hotel.service.OrderInfoService;
import com.umessage.hotel.service.OrderPmsService;
import com.umessage.hotel.service.RoomInfoService;
import com.umessage.hotel.service.WxCfgService;
import com.umessage.hotel.service.WxMsgTmplService;
import com.umessage.hotel.util.HotelConstant;
import com.umessage.hotel.util.RestResult;
import com.umessage.hotel.util.RestResultGenerator;
import com.umessage.hotel.util.XmlTool;
import com.umessage.system.domain.User;
import com.umessage.system.service.UserService;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

/**
 * 订单管理
 * 
 * @author mixiangliu
 *
 */
@Api("订单管理")
@RestController
@EnableAutoConfiguration
@RequestMapping("/rest/orders")
public class OrderResource extends BaseResourceController {

	@Autowired
	private OrderInfoService orderService;
	@Autowired
	private RoomInfoService roomInfoService;
	@Autowired
	private WxCfgService wxCfgService;
	@Autowired
	private MemberInfoService memberInfoService;
	@Autowired
	private RoomInfoService roomService;
	@Autowired
	private CouponService couponService;
	@Autowired
	private MemberCouponService memberCouponService;
	@Autowired
	private WxMsgTmplService wxMsgTmplService;
	@Autowired
	private UserService userService;
	@Autowired
	private RedissonService redissonService;
	@Autowired
	private OrderPmsService orderPmsService;
	@Autowired
	private MemberAccountLogService memberAccountLogService;
	@Autowired
	private FormService formService;
	@Autowired
	private OrderBreakfastService orderBreakfastService;

	private DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
	private DateFormat df2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	/**
	 * 创建订单
	 * 
	 * @param order
	 * @return
	 */
	@ApiOperation(value = "创建订单", notes = "创建订单")
	@RequestMapping(method = RequestMethod.POST)
	public RestResult<String> createOrder(OrderParam order, ServletRequest request) {
		try {
			assertMobileLogin(request);
			String memberId = (String) request.getAttribute("subject");
			String hotelId = (String) request.getAttribute("issuer");
			String openid = (String) request.getAttribute("openid");

			// 计算价格,防篡改
			RoomInfo roomInfo = roomService.getRoomAvgByRoomId(order.getRoomId(), hotelId,
					df.parse(order.getCheckinTime()), df.parse(order.getCheckoutTime()));
			MemberInfo memberInfo=this.memberInfoService.findMemberById(memberId);
			this.roomInfoService.getDisCountPrice(memberInfo, roomInfo);
			BigDecimal shouPayMonry = null;
			if(order.getPayType() == 2){ //担保支付 ,计算一天
				shouPayMonry = roomInfo.getDiscountPrice().multiply(BigDecimal.valueOf(order.getRoomCount()));// 平均价格*房间数
			}else{
				shouPayMonry = roomInfo.getDiscountPrice().multiply(BigDecimal.valueOf(order.getRoomCount()))
						.multiply(roomInfo.getCountDay()); // 平均价格 *房间数*天数
			}
			shouPayMonry = shouPayMonry.setScale(2, BigDecimal.ROUND_HALF_UP); // 保留二位
			
			// 判断是否含有优惠券
			String couponId = order.getCoupon_id();
			if (StringUtils.isNotBlank(couponId)) {
				//担保支付 不可使用优惠券
				if(order.getPayType() == 2) {
					return RestResultGenerator.genErrorResult("担保支付不可使用优惠券");
				}
				List<MemberCoupon> memberCouponList = memberCouponService.findCouponByUser(memberId, hotelId, couponId,"1");
				if(memberCouponList == null || ( memberCouponList.size() >0 && ! memberCouponList.get(0).getStatus().equals("0") ) ){ // 不合法类型  过期 的优惠券
					throw new RuntimeException("用户暂无有效优惠券");
				}
				Coupon coupon = couponService.getCouponById(couponId);// 查询优惠券金额
				if (coupon == null) {
					return RestResultGenerator.genErrorResult("非法的优惠券");
				}
				// 直减,满减 都取secondNumber
				if(coupon.getMode() == 1){ //直减
					if( shouPayMonry.compareTo(BigDecimal.valueOf(coupon.getSecondNumber())) <= 0 ){ // 应付金额  < 直减券
						shouPayMonry =BigDecimal.ZERO ; //全部减去
					}else{
						shouPayMonry = shouPayMonry.subtract(new BigDecimal(coupon.getSecondNumber())); // 实付金额减去直减券
					}
				}else if(coupon.getMode() == 2 ){
					shouPayMonry = shouPayMonry.subtract(new BigDecimal(coupon.getSecondNumber())); // 实付金额减去优惠券
				}
			}
			// 判断余额是否合法
			BigDecimal useBalance = order.getUseBalance();
			BigDecimal myBalance = memberInfo.getVirtMoney().add(memberInfo.getRealMoney());// 余额 =虚拟+实际
			if (useBalance != null && useBalance.compareTo(myBalance) == 1) {
				return RestResultGenerator.genErrorResult("非法篡改账户余额");
			}
			if (useBalance != null) {
				shouPayMonry = shouPayMonry.subtract(useBalance);// 应付金额扣除余额
			}

			if (shouPayMonry.compareTo(order.getTotalprice()) != 0) {
				return RestResultGenerator.genErrorResult("订单价格异常,应付金额为" + shouPayMonry);
			}

			OrderInfo orderInfo = new OrderInfo();
			BeanUtils.copyProperties(order, orderInfo, "");
			orderInfo.setTotalPrice(order.getTotalprice());
			orderInfo.setRoomUnitPrice(roomInfo.getOriginalPrice()); // 房间原始价格
			orderInfo.setOpenid(openid);
			orderInfo.setMemberId(memberId);
			orderInfo.setHotelId(Integer.valueOf(hotelId));
			orderInfo.setRoomId(Integer.valueOf(order.getRoomId()));
			orderInfo.setResident(order.getResident());
			orderInfo.setUseBalance(order.getUseBalance()); 
			orderInfo.setOrderAmount(roomInfo.getOriginalPrice().multiply(BigDecimal.valueOf(order.getRoomCount()))
					.multiply(roomInfo.getCountDay()));//订单原始价格
			orderInfo.setDiscountPrice(roomInfo.getDiscountPrice());//房间会员价格
			if (StringUtils.isNotBlank(order.getCoupon_id())) {
				orderInfo.setCouponId(Integer.parseInt(order.getCoupon_id()));
			}
			orderService.saveNewOrder(orderInfo);
			//保存formid
			FormModel form = new FormModel();
			form.setFormId(orderInfo.getFormId());
			form.setExpire(System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 7);//7天失效
			formService.saveFormId(openid, form);
			//到店支付，给会员发送短信
			if(order != null && order.getPayType() == 1) {
				orderService.sendSmsByOrderId("0", orderInfo.getOrderId());//发送短信
			}
			//待确认短信通知
			if(orderInfo.getPayType() == 1) {
				RBlockingQueue<String> waitConfirmQueue = redissonService.<String>getBlockingQueue("wait_confirm_order_queue");
				waitConfirmQueue.offer(orderInfo.getOrderId());
			}
			
			System.out.println("创建订单" + orderInfo.getOrderId() + "******" + new SimpleDateFormat("hh:mm:ss").format(new Date()));
			return RestResultGenerator.genSuccessResult(orderInfo.getOrderId());
		} catch (Exception e) {
			e.printStackTrace();
			return RestResultGenerator.genErrorResult(e.getMessage());
		}
	}

	/**
	 * 客户取消订单
	 * 
	 * @param orderId
	 * @param userId    用户id
	 * @param accountId 账户id
	 * @return
	 */
	@ApiOperation(value = "客户取消订单", notes = "客户取消订单")
	@RequestMapping(value = "/{orderId}/cancelOrderByMember", method = RequestMethod.POST)
	public RestResult cancelOrderByMember(@PathVariable("orderId") String orderId, String wxcfgid, String reason,
			ServletRequest request) {
		try {
			String type = (String) request.getAttribute("type");
			// 客户端绑定后登录
			if (HotelConstant.LOGIN_TYPE_MOBILE_ClIENT.equals(type)) {
				String hotelId = (String) request.getAttribute("issuer");
				String memberId = (String) request.getAttribute("subject");
				
				if( ! StringUtils.isNotBlank(wxcfgid)){ //查询员工端wxcfgid 
					 WxCfg queryWxCfg = wxCfgService.queryWxCfg(hotelId, "1");
					 wxcfgid = (wxcfgid == null ? queryWxCfg.getWxcfgid() : null) ;
				}
				this.orderService.cancelOrderByMember(wxcfgid, hotelId, memberId, orderId, reason);
				
				//查询优惠券id
				OrderInfo SingleOrder = orderService.findSingleOrder(memberId, orderId);
				//存在优惠券,释放优惠券
				if( null != SingleOrder.getCouponId()  ){
					memberCouponService.updateStatus(memberId,Integer.parseInt(hotelId),SingleOrder.getCouponId(),"1","0");
				}
				//释放早餐券
				OrderBreakfast obf=new OrderBreakfast();
				obf.setBkfOrderId(orderId);
				this.orderBreakfastService.delCouponsByCon(obf);
				
				//取消订单消息队列
				RBlockingQueue<String> cancelOrderQueue = redissonService.<String>getBlockingQueue("cancel_order_queue");
				cancelOrderQueue.offer(SingleOrder.getOrderId());
				
				return RestResultGenerator.genSuccessResult();
			}
			return RestResultGenerator.genSuccessResult();
		} catch (Exception e) {
			e.printStackTrace();
			return RestResultGenerator.genErrorResult(e.getMessage());
		}
	}

	/**
	 * 酒店取消订单
	 * 
	 * @param orderId
	 * @param userId    用户id
	 * @param accountId 账户id
	 * @return
	 */
	@ApiOperation(value = "酒店取消订单", notes = "酒店取消订单")
	@RequestMapping(value = "/{orderId}/cancelOrderByHotel", method = RequestMethod.POST)
	public RestResult cancelOrderByHotel(@PathVariable("orderId") String orderId, String wxcfgid, String reason,
			ServletRequest request) {
		try {
			String type = (String) request.getAttribute("type");
			if (HotelConstant.LOGIN_TYPE_MOBILE_HOTEL.equals(type)) {
				String hotelId = (String) request.getAttribute("issuer");
				String accountId = (String) request.getAttribute("subject");
				
				if( ! StringUtils.isNotBlank(wxcfgid)){ //查询酒店端wxcfgid 
					 WxCfg queryWxCfg = wxCfgService.queryWxCfg(hotelId, "1");
					 wxcfgid =  (queryWxCfg == null ? null :queryWxCfg.getWxcfgid());
				}
				this.orderService.cancelOrderByHotel(wxcfgid, hotelId, accountId, orderId, reason);
				
				//查询优惠券id
				OrderInfo SingleOrder = orderService.findSingleOrder(null, orderId);
				//存在优惠券,释放优惠券
				if( null != SingleOrder.getCouponId()  ){
					memberCouponService.updateStatus(SingleOrder.getMemberId(),Integer.parseInt(hotelId),SingleOrder.getCouponId(),"1","0");
				}
				//释放早餐券
				OrderBreakfast obf=new OrderBreakfast();
				obf.setBkfOrderId(orderId);
				this.orderBreakfastService.delCouponsByCon(obf);
				
				//发送模版消息
				wxMsgTmplService.sendCancelOrderMsg(SingleOrder);
				//发送短信通知
				orderService.sendSms("2", SingleOrder);
				
				return RestResultGenerator.genSuccessResult();
			}
			return RestResultGenerator.genSuccessResult();
		} catch (Exception e) {
			e.printStackTrace();
			return RestResultGenerator.genErrorResult(e.getMessage());
		}

	}

	/**
	 * 确认订单
	 * 
	 * @param order
	 * @return
	 */
	@ApiOperation(value = "确认订单", notes = "确认订单")
	@RequestMapping(value = "/{orderId}/confirm", method = RequestMethod.POST)
	public RestResult confirmOrder(@PathVariable("orderId") String orderId, ServletRequest request) {
		String type = (String) request.getAttribute("type");
		try {
			if (HotelConstant.LOGIN_TYPE_MOBILE_HOTEL.equals(type)) {
				OrderInfo orderInfo = orderService.selectByKey(orderId);
				String hotelId = (String) request.getAttribute("issuer");
				String accountId = (String) request.getAttribute("subject");
				orderService.confirmOrder(hotelId, accountId, orderId);
				//发送微信模版消息
				wxMsgTmplService.sendConfirmOrderMsg(orderInfo);
				//发送短信通知
				orderService.sendSms("1", orderInfo);
				
				//发放早餐券
				orderBreakfastService.addOrderBreakfastByRoomInfo(orderInfo);
				
				return RestResultGenerator.genSuccessResult();
			}
			return RestResultGenerator.genErrorResult("invalid session");
		} catch (Exception e) {
			e.printStackTrace();
			return RestResultGenerator.genErrorResult(e.getMessage());
		}
	}

	/**
	 * 订单支付
	 * 
	 * @param order
	 * @return
	 */
	@ApiOperation(value = "订单支付", notes = "订单支付")
	@RequestMapping(value = "/{orderId}/payOrder", method = RequestMethod.POST)
	public RestResult<PaySignModel> payOrder(@PathVariable("orderId") String orderId, String wxcfgid,
			ServletRequest request) {
		try {
			String openid = (String) request.getAttribute("openid");
			String appid = (String) request.getAttribute("appid");
			String createdIp = request.getRemoteAddr();
			
			PaySignModel paySignModel = orderService.createUnifiedOrder(wxcfgid, openid, createdIp, orderId);

			if(paySignModel !=null && paySignModel.getAppId().equals("no pay")){ 
				return RestResultGenerator.genSuccessResult(null);
			}
			if (paySignModel == null) {
				return RestResultGenerator.genErrorResult("can not find specified app configuration");
			} else {
				return RestResultGenerator.genSuccessResult(paySignModel);
			}
		} catch (Exception e) {
			e.printStackTrace();
			return RestResultGenerator.genErrorResult(e.getMessage());
		}
	}

	/**
	 * 支付状态
	 * 
	 * @param order
	 * @return
	 */
	@ApiOperation(value = "支付状态", notes = "支付状态")
	@RequestMapping(value = "/{orderId}/payStatus", method = RequestMethod.POST)
	public RestResult payStatus(String orderId, ServletRequest request) {
		OrderInfo order = this.orderService.selectByKey(orderId);
		if (order == null) {
			return RestResultGenerator.genErrorResult("invalid order id");
		}
		return RestResultGenerator.genSuccessResult(order.getPayStatus());
	}

	/**
	 * 支付通知
	 * 
	 * @param order
	 * @return
	 */
	@Log
	@RequestMapping(value = "/{wxcfgid}/{orderId}/payNotify", method = RequestMethod.POST)
	public void payNotify(@PathVariable("wxcfgid") String wxcfgid, @PathVariable("orderId") String orderId,
			ServletRequest request) {
		try (InputStream ins = request.getInputStream();) {
			byte[] bs = new byte[1024];
			int i = 0;
			String str = "";
			while ((i = ins.read(bs)) != -1) {
				str += new String(bs, 0, i);
			}

			JSONObject json = XmlTool.documentToJSONObject(str);
			PayResult res = JSON.toJavaObject(json, PayResult.class);

			if ("SUCCESS".equals(res.getResult_code())) {
				String outTradeNo = res.getOut_trade_no();
				if (outTradeNo != null && outTradeNo.equals(orderId)) {
					OrderInfo order = this.orderService.selectByKey(orderId);
					// 验证订单id
					if (order == null) {
						throw new RuntimeException("invalid order id , orderId  is "+ orderId);
					}
					// 状态已支付直接返回
					if (order.getPayStatus() == 1) {
						return;
					}
					// 验证签名
					SortedMap<String, Object> generals = new TreeMap<>();
					XmlTool.JsonToMap(json, generals);
					generals.remove("sign");
					WxCfg wxcfg = wxCfgService.selectByKey(wxcfgid);
					String sign = SignatureUtil.sign(generals, wxcfg.getAppkey());
					if (!sign.equals(json.get("sign"))) {
						throw new RuntimeException("pay notify sign invalid(支付通知无效)");
					}
					BigDecimal totalFee = new BigDecimal(res.getTotal_fee());
					// 判断金额是否相等 
					if(totalFee.compareTo(order.getTotalPrice().multiply(BigDecimal.valueOf(100)))!= 0) {
						  throw new RuntimeException("invalid order notify(非法的同步消息)"); 
					}
					// 更新订单状态
					order.setPayStatus(1);
					orderService.updateAll(order);
					
					//查询订单下的所有消费记录
					List<MemberAccountLog> AccountList = memberInfoService.getConsumingRecordByUser(null, null, orderId,"0");
					if(null != AccountList && AccountList.size()>0){
						for (MemberAccountLog account : AccountList) {
							account.setPayStatus("1");
							memberAccountLogService.updateNotNull(account);
						}
					}
					//发送模版消息
					wxMsgTmplService.sendOrderPaySuccessMsg(order);
					//发送短信通知
					orderService.sendSms("3", order);
					//将订单id放到待确认订单队列
					RBlockingQueue<String> waitConfirmQueue = redissonService.<String>getBlockingQueue("wait_confirm_order_queue");
					waitConfirmQueue.offer(order.getOrderId());
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 获取用户单个订单
	 * 
	 * @param orderId
	 * @return
	 */
	@ApiOperation(value = "获取用户单个订单", notes = "获取用户单个订单")
	@RequestMapping(value = "/{orderId}", method = RequestMethod.GET)
	public RestResult<OrderModel> loadOrder(@PathVariable("orderId") String orderId, ServletRequest request) {
		try {
			assertMobileLogin(request);

			String type = (String) request.getAttribute("type");
			String memberId = (String) request.getAttribute("subject");

			OrderInfo orderInfo = null;
			// 会员
			if (HotelConstant.LOGIN_TYPE_MOBILE_ClIENT.equals(type)) {
				orderInfo = orderService.findSingleOrder(memberId, orderId);
			}
			// 员工
			if (HotelConstant.LOGIN_TYPE_MOBILE_HOTEL.equals(type)) {
				orderInfo = orderService.findSingleOrder(null, orderId);
			}
			if (orderInfo == null) {
				return RestResultGenerator.genErrorResult("invalid order id is ");
			}
			OrderModel order = new OrderModel();
			BeanUtils.copyProperties(orderInfo, order);
			order.setBookTime(orderInfo.getBookTime() != null ? df2.format(orderInfo.getBookTime()) : "");
			order.setCheckinTime(
					orderInfo.getCheckinTime() != null ? df2.format(df2.parse(orderInfo.getCheckinTime())) : "");
			order.setCheckoutTime(
					orderInfo.getCheckoutTime() != null ? df2.format(df2.parse(orderInfo.getCheckoutTime())) : "");
			order.setConfirmTime(orderInfo.getConfirmTime() != null ? df2.format(orderInfo.getConfirmTime()) : "");
			// 查询订单中的优惠券金额
			if (orderInfo.getCouponId() != null) {
				Coupon coupon = couponService.getCouponById(orderInfo.getCouponId() + "");
				if (coupon != null) {
					if(coupon.getMode() == 1 && order.getOrderAmount().compareTo(new BigDecimal(coupon.getSecondNumber()))<0  ){//直减券大于 应付金额
						order.setCouponMoney(order.getOrderAmount()+"");
					}else{
						order.setCouponMoney(coupon.getSecondNumber()+"");
					}
				}
			}
			RoomInfo room = roomService.getRoomAvgByRoomId(orderInfo.getRoomId() + "", orderInfo.getHotelId() + "",
					df.parse(order.getCheckinTime()), df.parse(order.getCheckoutTime()));
			RoomModel roomModel = roomInfoService.convertToRoomModel(room, null,null);
			Map<String, String> facilities = roomModel.getPolicies();
			boolean flage = true;
			if(null!= facilities   ){
				for (Entry<String, String> entry : facilities.entrySet()) {
					if("不可退款".equals(entry.getValue()) ){
						if(! "".equals(orderInfo.getNotCancle())){
							facilities.put(entry.getKey(), orderInfo.getNotCancle());
						}else{
							facilities.remove(entry.getKey());
						}
						flage =false;
						break;
					}
				}
			}
			if(flage){
				if(orderInfo.getNotCancle() != null && !"".equals(orderInfo.getNotCancle())){
					facilities.put("1024", orderInfo.getNotCancle());
				}
			}
			roomModel.setName(orderInfo.getName());
			order.setRoomInfo(roomModel);
			
			return RestResultGenerator.genSuccessResult(order);
		} catch (Exception e) {
			e.printStackTrace();
			return RestResultGenerator.genErrorResult(e.getMessage());
		}
	}

	/**
	 * 获取订单列表
	 * 
	 * @param hotelId
	 * @param userId
	 * @param orderStatus
	 * @param pageSize
	 * @param pageNum
	 * @return
	 */
	@ApiOperation(value = "获取订单列表", notes = "获取订单列表")
	@RequestMapping(method = RequestMethod.GET)
	public RestResult<List<OrderModel>> list(@RequestParam(defaultValue = "", required = true) String orderStatus,
			@RequestParam(defaultValue = "1", required = true) int page,
			@RequestParam(defaultValue = "10", required = true) int rows, ServletRequest request) {

		try {
			assertMobileLogin(request);

			String type = (String) request.getAttribute("type");
			String subject = (String) request.getAttribute("subject");
			String hotelId = (String) request.getAttribute("issuer");

			List<OrderModel> list = new ArrayList<OrderModel>();
			List<OrderInfo> orderList = new ArrayList<OrderInfo>();

			// 会员
			if (HotelConstant.LOGIN_TYPE_MOBILE_ClIENT.equals(type)) {
				orderList = orderService.findUserOrderList(subject, orderStatus, page, rows);
			}
			// 员工
			if (HotelConstant.LOGIN_TYPE_MOBILE_HOTEL.equals(type)) {
				orderList = orderService.findHotelOrderList(hotelId, orderStatus, page, rows);
			}

			if (orderList != null && orderList.size() > 0) {
				for (OrderInfo orderInfo : orderList) {
					OrderModel orderModel = new OrderModel();
					BeanUtils.copyProperties(orderInfo, orderModel);
					orderModel.setBookTime(orderInfo.getBookTime() != null ? df2.format(orderInfo.getBookTime()) : "");
					orderModel.setCheckinTime(
							orderInfo.getCheckinTime() != null ? df2.format(df2.parse(orderInfo.getCheckinTime())) : "");
					orderModel.setCheckoutTime(
							orderInfo.getCheckoutTime() != null ? df2.format(df2.parse(orderInfo.getCheckoutTime())) : "");
					orderModel.setConfirmTime(
							orderInfo.getConfirmTime() != null ? df2.format(orderInfo.getConfirmTime()) : "");
					
					RoomModel roomModel = new RoomModel();
					roomModel.setName(orderInfo.getName());
					roomModel.setNotCancle(orderInfo.getNotCancle());
					orderModel.setRoomInfo(roomModel);
					list.add(orderModel);
				}
			}
			return RestResultGenerator.genSuccessResult(list);
		} catch (Exception e) {
			e.printStackTrace();
			return RestResultGenerator.genErrorResult(e.getMessage());
		}
	}

	/**
	 * 统计订单数
	 * 
	 * @param hotelId
	 * @param userId
	 * @param orderStatus
	 * @return
	 */
	@ApiOperation(value = "统计订单数", notes = "统计订单数(员工端使用)")
	@RequestMapping(value = "countOrders", method = RequestMethod.GET)
	public RestResult<Integer> countOrders(String orderStatus, String startTime, String endTime,
			ServletRequest request) {
		try {
			assertMobileLogin(request);
  
			String type = (String) request.getAttribute("type");
			String subject = (String) request.getAttribute("subject");
			String hotelId = (String) request.getAttribute("issuer");

			if (HotelConstant.LOGIN_TYPE_WX.equals(type)) {
				return RestResultGenerator.genErrorResult("invalid session type");
			}
			Integer orderCount = this.orderService.countOrders(hotelId, orderStatus, startTime, endTime);
			return RestResultGenerator.genSuccessResult(orderCount);
		} catch (Exception e) {
			e.printStackTrace();
			return RestResultGenerator.genErrorResult(e.getMessage());
		}
	}
	
	
	/**
	 *       统计用户（待付款、待确认、已完成、已取消）订单数量
	 * 
	 * @param hotelId
	 * @param userId
	 * @param orderStatus
	 * @author 边宏飞
	 * @return 
	 */
	@ApiOperation(value = "统计用户（待确认、已完成、取消）订单数量", notes = "统计订单数(H端使用)")
	@RequestMapping(value = "countMemberAllTypeOrders", method = RequestMethod.GET)
	public RestResult<Map<String, Integer>> countMemberAllTypeOrders(String startTime, String endTime,
			ServletRequest request) {
		try {
			assertMobileLogin(request);
			
			String type = (String) request.getAttribute("type");
			String subject = (String) request.getAttribute("subject");
			String hotelId = (String) request.getAttribute("issuer");
			
			if (HotelConstant.LOGIN_TYPE_WX.equals(type)) {
				return RestResultGenerator.genErrorResult("invalid session type");
			}
			String checkinTime = new SimpleDateFormat("YYYY-MM-dd 00:00:00").format(new Date()) ;
			Integer orderCount0 = this.orderService.countMemberTypeOrders(hotelId, subject, "0", "0", checkinTime, endTime);
			Integer orderCount1 = this.orderService.countMemberConfirmedOrders(hotelId, subject, "1", "0", checkinTime, endTime);
			Integer orderCount2 = this.orderService.countMemberOrders(hotelId, subject, "1", null, null);
			Integer orderCount3 = this.orderService.countMemberOrders(hotelId, subject, "2", checkinTime, endTime);
			Integer orderCount4 = this.orderService.countMemberOrders(hotelId, subject, "3", checkinTime, endTime);
			Map<String, Integer> memberTypeOrderCount = new HashMap<String, Integer>() ;
			memberTypeOrderCount.put("orderCount0", orderCount0) ;    // 0：待支付
			memberTypeOrderCount.put("orderCount1", orderCount1) ;    // 1：待确认
			memberTypeOrderCount.put("orderCount2", orderCount2) ;	  // 2:  已确认--待入住
			memberTypeOrderCount.put("orderCount3", orderCount3) ;    // 3:已取消
			memberTypeOrderCount.put("orderCount4", orderCount4) ;    // 3:已入住 完成
			
			return RestResultGenerator.genSuccessResult(memberTypeOrderCount);
		} catch (Exception e) {
			e.printStackTrace();
			return RestResultGenerator.genErrorResult(e.getMessage());
		}
	}
	
	/**
	 * h统计待确认订单数
	 */
	@ApiOperation(value = "统计待确认订单数", notes = "统计待确认订单数")
	@RequestMapping(value = "countWaitOrder" , method = RequestMethod.GET)
	public  RestResult<Integer> countWaitOrder(ServletRequest request){
		try {
			assertMobileLogin(request);

			String type = (String) request.getAttribute("type");
			String subject = (String) request.getAttribute("subject");
			String hotelId = (String) request.getAttribute("issuer");
			
			// 员工  查询待确认订单
			if (HotelConstant.LOGIN_TYPE_MOBILE_HOTEL.equals(type)) {
				//订单状态0,支付状态0
				int count = orderService.countWaitOrder(hotelId,"0","0");
				return RestResultGenerator.genSuccessResult(count);
			}
			return RestResultGenerator.genErrorResult("非酒店端登录"+type);
		} catch (Exception e) {
			e.printStackTrace();
			return RestResultGenerator.genErrorResult(e.getMessage());
		}
	}

	/**
	 * 统计订单收入
	 * 
	 * @param hotelId
	 * @return
	 */
	@ApiOperation(value = "统计订单收入", notes = "统计订单收入(员工端使用)")
	@RequestMapping(value = "countOrdersIncome", method = RequestMethod.GET)
	public RestResult<BigDecimal> countOrdersIncome(String startTime, String endTime, ServletRequest request) {

		try {
			assertMobileLogin(request);

			String type = (String) request.getAttribute("type");
			String subject = (String) request.getAttribute("subject");
			String hotelId = (String) request.getAttribute("issuer");

			if (HotelConstant.LOGIN_TYPE_WX.equals(type)) {
				return RestResultGenerator.genErrorResult("invalid session type");
			}

			BigDecimal ordersIncome = this.orderService.countOrdersIncome(hotelId, startTime, endTime);
			return RestResultGenerator.genSuccessResult(ordersIncome);
		} catch (Exception e) {
			e.printStackTrace();
			return RestResultGenerator.genErrorResult(e.getMessage());
		}

	}

	/**
	 * "待支付" 订单列表
	 * 
	 * @param hotelId
	 * @param userId
	 * @param orderStatus
	 * @param pageSize
	 * @param pageNum
	 * @return
	 */
	@ApiOperation(value = "待支付-订单列表", notes = "待支付-订单列表")
	@RequestMapping(value = "waitPay", method = RequestMethod.GET)
	public RestResult<List<OrderModel>> waitPay(@RequestParam(defaultValue = "1", required = true) int page,
			@RequestParam(defaultValue = "10", required = true) int rows, ServletRequest request) {

		try {
			assertMobileLogin(request);

			String type = (String) request.getAttribute("type");
			String subject = (String) request.getAttribute("subject");
			String hotelId = (String) request.getAttribute("issuer");

			List<OrderModel> list = new ArrayList<OrderModel>();
			List<OrderInfo> orderList = new ArrayList<OrderInfo>();

			// 会员     // 订单状态不能为已经取消的(2)
			if (HotelConstant.LOGIN_TYPE_MOBILE_ClIENT.equals(type)) {
				orderList = orderService.findUserOrderListByMoreState(subject, "13", "0", page, rows);
			}
			// 员工(h端暂无)
			if (HotelConstant.LOGIN_TYPE_MOBILE_HOTEL.equals(type)) {
				orderList = orderService.findHotelOrderListByMoreState(hotelId, "13", "0", page, rows);
			}
			if (orderList != null && orderList.size() > 0) {
				for (OrderInfo orderInfo : orderList) {
					OrderModel orderModel = new OrderModel();
					BeanUtils.copyProperties(orderInfo, orderModel);
					formatOrderTime(orderInfo, orderModel);
					
					RoomModel roomModel = new RoomModel();
					roomModel.setName(orderInfo.getName());
					roomModel.setNotCancle(orderInfo.getNotCancle());
					orderModel.setRoomInfo(roomModel);
					list.add(orderModel);
				}
			}
			return RestResultGenerator.genSuccessResult(list);
		} catch (Exception e) {
			e.printStackTrace();
			return RestResultGenerator.genErrorResult(e.getMessage());
		}
	}

	/**
	 * “待确认”订单列表
	 * 
	 * @param hotelId
	 * @param userId
	 * @param orderStatus
	 * @param pageSize
	 * @param pageNum
	 * @return
	 */
	@ApiOperation(value = "待确认-订单列表", notes = "待确认-订单列表")
	@RequestMapping(value = "waitConfirm", method = RequestMethod.GET)
	public RestResult<List<OrderModel>> waitConfirm(@RequestParam(defaultValue = "1", required = true) int page,
			@RequestParam(defaultValue = "10", required = true) int rows, ServletRequest request) {

		try {
			assertMobileLogin(request);

			String type = (String) request.getAttribute("type");
			String subject = (String) request.getAttribute("subject");
			String hotelId = (String) request.getAttribute("issuer");

			List<OrderModel> list = new ArrayList<OrderModel>();
			List<OrderInfo> orderList = new ArrayList<OrderInfo>();

			// 会员
			if (HotelConstant.LOGIN_TYPE_MOBILE_ClIENT.equals(type)) {	
				//支付状态为 1,2,3
				orderList = orderService.findUserOrderListByMoreState(subject, "0", "123", page, rows);
			}
			// 员工
			if (HotelConstant.LOGIN_TYPE_MOBILE_HOTEL.equals(type)) {
				//支付状态为 1,2,3
				orderList = orderService.findHotelOrderListByMoreState(hotelId, "0", "123", page, rows);
			}

			if (orderList != null && orderList.size() > 0) {
				for (OrderInfo orderInfo : orderList) {
					OrderModel orderModel = new OrderModel();
					BeanUtils.copyProperties(orderInfo, orderModel);
					formatOrderTime(orderInfo, orderModel);
					
					RoomModel roomModel = new RoomModel();
					roomModel.setName(orderInfo.getName());
					roomModel.setNotCancle(orderInfo.getNotCancle());
					orderModel.setRoomInfo(roomModel);
					list.add(orderModel);
				}
			}
			return RestResultGenerator.genSuccessResult(list);
		} catch (Exception e) {
			e.printStackTrace();
			return RestResultGenerator.genErrorResult(e.getMessage());
		}
	}
	
	/**
	 * “待入住”订单列表
	 * 暂无调用
	 * @param hotelId
	 * @param userId
	 * @param orderStatus
	 * @param pageSize
	 * @param pageNum
	 * @return
	 */
	@ApiOperation(value = "待入住-订单列表", notes = "待入住-订单列表")
	@RequestMapping(value = "waitCheckIn", method = RequestMethod.GET)
	public RestResult<List<OrderModel>> waitCheckIn(@RequestParam(defaultValue = "1", required = true) int page,
			@RequestParam(defaultValue = "10", required = true) int rows, ServletRequest request) {

		try {
			assertMobileLogin(request);

			String type = (String) request.getAttribute("type");
			String subject = (String) request.getAttribute("subject");
			String hotelId = (String) request.getAttribute("issuer");

			List<OrderModel> list = new ArrayList<OrderModel>();
			List<OrderInfo> orderList = new ArrayList<OrderInfo>();

			// 会员
			if (HotelConstant.LOGIN_TYPE_MOBILE_ClIENT.equals(type)) {
				orderList = orderService.findUserOrderListByUnCheckIn(subject, page, rows);
			}
			// 员工
			if (HotelConstant.LOGIN_TYPE_MOBILE_HOTEL.equals(type)) {
				orderList = orderService.findHotelOrderListByUnCheckIn(hotelId, page, rows);
			}
			if (orderList != null && orderList.size() > 0) {
				for (OrderInfo orderInfo : orderList) {
					OrderModel orderModel = new OrderModel();
					BeanUtils.copyProperties(orderInfo, orderModel);
					formatOrderTime(orderInfo, orderModel);
					
					RoomModel roomModel = new RoomModel();
					roomModel.setName(orderInfo.getName());
					roomModel.setNotCancle(orderInfo.getNotCancle());
					orderModel.setRoomInfo(roomModel);
					list.add(orderModel);
				}
			}
			return RestResultGenerator.genSuccessResult(list);
		} catch (Exception e) {
			e.printStackTrace();
			return RestResultGenerator.genErrorResult(e.getMessage());
		}
	}

	/**
	 * “已确认”订单列表(待入住)
	 * 
	 * @param hotelId
	 * @param userId
	 * @param orderStatus
	 * @param pageSize
	 * @param pageNum
	 * @return
	 */
	@ApiOperation(value = "已确认-订单列表", notes = "已确认-订单列表")
	@RequestMapping(value = "haveBeenConfirmed", method = RequestMethod.GET)
	public RestResult<List<OrderModel>> haveBeenConfirmed(@RequestParam(defaultValue = "1", required = true) int page,
			@RequestParam(defaultValue = "10", required = true) int rows, ServletRequest request) {
		try {
			assertMobileLogin(request);

			String type = (String) request.getAttribute("type");
			String subject = (String) request.getAttribute("subject");
			String hotelId = (String) request.getAttribute("issuer");

			List<OrderModel> list = new ArrayList<OrderModel>();
			List<OrderInfo> orderList = new ArrayList<OrderInfo>();

			// 会员
			if (HotelConstant.LOGIN_TYPE_MOBILE_ClIENT.equals(type)) {
				orderList = orderService.findUserOrderList(subject, "1", page, rows);
			}
			// 员工
			if (HotelConstant.LOGIN_TYPE_MOBILE_HOTEL.equals(type)) {
				orderList = orderService.findConfirmOrderListSql(hotelId, "1", page, rows);  
//				orderList = orderService.findHotelOrderList(hotelId, "1", page, rows);
			}

			if (orderList != null && orderList.size() > 0) {
				for (OrderInfo orderInfo : orderList) {
					OrderModel orderModel = new OrderModel();
					BeanUtils.copyProperties(orderInfo, orderModel);
					formatOrderTime(orderInfo, orderModel);
					
					RoomModel roomModel = new RoomModel();
					roomModel.setName(orderInfo.getName());
					roomModel.setNotCancle(orderInfo.getNotCancle());
					orderModel.setRoomInfo(roomModel);
					list.add(orderModel);
				}
			}
			return RestResultGenerator.genSuccessResult(list);
		} catch (Exception e) {
			e.printStackTrace();
			return RestResultGenerator.genErrorResult(e.getMessage());
		}
	}

	/**
	 * “已取消”订单列表
	 * 
	 * @param hotelId
	 * @param userId
	 * @param orderStatus
	 * @param pageSize
	 * @param pageNum
	 * @return
	 */
	@ApiOperation(value = "已取消-订单列表", notes = "已取消-订单列表")
	@RequestMapping(value = "haveBeenCancelled", method = RequestMethod.GET)
	public RestResult<List<OrderModel>> haveBeenCancelled(@RequestParam(defaultValue = "1", required = true) int page,
			@RequestParam(defaultValue = "10", required = true) int rows, ServletRequest request) {

		try {
			assertMobileLogin(request);

			String type = (String) request.getAttribute("type");
			String subject = (String) request.getAttribute("subject");
			String hotelId = (String) request.getAttribute("issuer");

			List<OrderModel> list = new ArrayList<OrderModel>();
			List<OrderInfo> orderList = new ArrayList<OrderInfo>();

			// 会员
			if (HotelConstant.LOGIN_TYPE_MOBILE_ClIENT.equals(type)) {
				orderList = orderService.findUserOrderList(subject, "2", page, rows);
			}
			// 员工
			if (HotelConstant.LOGIN_TYPE_MOBILE_HOTEL.equals(type)) {
				orderList = orderService.findCancleOrderListSql(hotelId, "2", page, rows);
			}
			if (orderList != null && orderList.size() > 0) {
				for (OrderInfo orderInfo : orderList) {
					OrderModel orderModel = new OrderModel();
					BeanUtils.copyProperties(orderInfo, orderModel);
					formatOrderTime(orderInfo, orderModel);
					
					RoomModel roomModel = new RoomModel();
					roomModel.setName(orderInfo.getName());
					roomModel.setNotCancle(orderInfo.getNotCancle());
					orderModel.setRoomInfo(roomModel);
					list.add(orderModel);
				}
			}
			return RestResultGenerator.genSuccessResult(list);
		} catch (Exception e) {
			e.printStackTrace();
			return RestResultGenerator.genErrorResult(e.getMessage());
		}
	}

	/**
	 * 全部订单列表
	 * 
	 * @param hotelId
	 * @param userId
	 * @param orderStatus
	 * @param pageSize
	 * @param pageNum
	 * @return
	 */
	@ApiOperation(value = "全部订单列表", notes = "全部订单列表")
	@RequestMapping(value = "listAll", method = RequestMethod.GET)
	public RestResult<List<OrderModel>> listAll(@RequestParam(defaultValue = "1", required = true) int page,
			@RequestParam(defaultValue = "10", required = true) int rows, ServletRequest request) {
		try {
			assertMobileLogin(request);

			String type = (String) request.getAttribute("type");
			String subject = (String) request.getAttribute("subject");
			String hotelId = (String) request.getAttribute("issuer");

			List<OrderModel> list = new ArrayList<OrderModel>();
			List<OrderInfo> orderList = new ArrayList<OrderInfo>();

			// 会员
			if (HotelConstant.LOGIN_TYPE_MOBILE_ClIENT.equals(type)) {
				orderList = orderService.findUserOrderList(subject, null, page, rows);
			}
			// 员工  (order-status 0,1,2,3  - 未支付+未确认,未支付+已取消)
			if (HotelConstant.LOGIN_TYPE_MOBILE_HOTEL.equals(type)) {
				orderList = orderService.findHotelOrderAll(hotelId, page, rows);
			}
			if (orderList != null && orderList.size() > 0) {
				for (OrderInfo orderInfo : orderList) {
					if (HotelConstant.LOGIN_TYPE_MOBILE_HOTEL.equals(type)) {// 员工
						if("2".equals(orderInfo.getOrderStatus())) {//取消的订单
							if(orderInfo.getCancelPerson()==null) {
								orderInfo.setStaffName("订单超时取消");
							}else {
								if(orderInfo .getCancelType() ==1 ){ //员工取消
									User user = this.userService.getUserByid(Long.parseLong(orderInfo.getCancelPerson()));
									if(user != null){
										orderInfo.setStaffName(user.getUsername());
									}
								}/*else if(orderInfo .getCancelType() ==2) { //会员取消(暂不显示)
									MemberInfo memberInfo = this.memberInfoService.getMemberInfoForUpdate(orderInfo.getCancelPerson());
									orderInfo.setStaffName(memberInfo.getMobile());
								}*/
							}
						}
						if("1".equals(orderInfo.getOrderStatus())) {//确认的订单
							if(null != orderInfo.getConfirmPerson()){
								User user = this.userService.getUserByid(Long.parseLong(orderInfo.getConfirmPerson()));
								if(null != user){
									orderInfo.setStaffName(user.getUsername());
								}
							}
						}
					}
					OrderModel orderModel = new OrderModel();
					BeanUtils.copyProperties(orderInfo, orderModel);
					formatOrderTime(orderInfo, orderModel);//格式化时间
					
					RoomModel roomModel = new RoomModel();
					roomModel.setName(orderInfo.getName());
					roomModel.setNotCancle(orderInfo.getNotCancle());
					orderModel.setRoomInfo(roomModel);
					list.add(orderModel);
				}
			}
			return RestResultGenerator.genSuccessResult(list);
		} catch (Exception e) {
			e.printStackTrace();
			return RestResultGenerator.genErrorResult(e.getMessage());
		}
	}
	
	/**
	 * 已入住订单列表
	 * @return
	 */
	@ApiOperation(value = "已入住-订单列表", notes = "已入住-订单列表")
	@RequestMapping(value="checkIn" ,method = RequestMethod.GET)
	public RestResult<List<OrderModel>> CheckInList(@RequestParam(defaultValue = "1", required = true) int page,
			@RequestParam(defaultValue = "10", required = true) int rows, ServletRequest request) {
		try {
			assertMobileLogin(request);

			String type = (String) request.getAttribute("type");
			String memberId = (String) request.getAttribute("subject");
			String hotelId = (String) request.getAttribute("issuer");

			List<OrderModel> list = new ArrayList<OrderModel>();
			List<OrderInfo> orderList = new ArrayList<OrderInfo>();

			// 会员
			if (HotelConstant.LOGIN_TYPE_MOBILE_ClIENT.equals(type)) {
				orderList = orderService.findUserOrderList(memberId, "3", page, rows);
			}
			// 员工
			if (HotelConstant.LOGIN_TYPE_MOBILE_HOTEL.equals(type)) {
				orderList = orderService.findHotelOrderList(hotelId, "3", page, rows);
			}
			if (orderList != null && orderList.size() > 0) {
				for (OrderInfo orderInfo : orderList) {
					OrderModel orderModel = new OrderModel();
					BeanUtils.copyProperties(orderInfo, orderModel);
					orderModel.setBookTime(orderInfo.getBookTime() != null ? df.format(orderInfo.getBookTime()) : "");
					orderModel.setConfirmTime(
							orderInfo.getConfirmTime() != null ? df.format(orderInfo.getConfirmTime()) : "");
					orderModel.setCheckinTime(
							orderInfo.getCheckinTime() != null ? df2.format(df2.parse(orderInfo.getCheckinTime())) : "");
					orderModel.setCheckoutTime(
							orderInfo.getCheckoutTime() != null ? df2.format(df2.parse(orderInfo.getCheckoutTime())) : "");
					
					RoomModel roomModel = new RoomModel();
					roomModel.setName(orderInfo.getName());
					roomModel.setNotCancle(orderInfo.getNotCancle());
					orderModel.setRoomInfo(roomModel);
					list.add(orderModel);
				}
			}
			return RestResultGenerator.genSuccessResult(list);
		}  catch (Exception e) {
			e.printStackTrace();
			return RestResultGenerator.genErrorResult(e.getMessage());
		}
	}

	private void formatOrderTime(OrderInfo orderInfo, OrderModel orderModel) throws ParseException {
		orderModel.setBookTime(orderInfo.getBookTime() != null ? df.format(orderInfo.getBookTime()) : "");
		orderModel.setConfirmTime(
				orderInfo.getConfirmTime() != null ? df.format(orderInfo.getConfirmTime()) : "");
		orderModel.setCheckinTime(
				orderInfo.getCheckinTime() != null ? df2.format(df2.parse(orderInfo.getCheckinTime())) : "");
		orderModel.setCheckoutTime(
				orderInfo.getCheckoutTime() != null ? df2.format(df2.parse(orderInfo.getCheckoutTime())) : "");
	}
}
